import fs from 'fs'
import { reflectComponent, reflectDesc, reflectInputNumberParams, reflectOptions } from './mysqlreflect.js'
import { checkbox, radio, datePicker, datimePicker, input, textarea, select, timePicker, formSwitch, inputNumber, elSelect, uploadImage, richText, tag, dateRange, searchElSelect } from './registerComs.js'
import { formatToHump, formatToUpHump } from './utils.js'
let config = {}
// add update detail
export const createViewTemplate = (columns, tableName, type = 'add') => {
  fs.readFile('src/scripts/config.json', 'utf8', (err, data) => {
    if (err) throw err
    config = JSON.parse(data)
    const humpTableName = formatToHump(tableName)
    const folder = `${config.view.folder}/${humpTableName}`
    const fileName = `${folder}/${type}.vue`
    // verify file is exist or not
    const formFileName = `@/${config.vendorFolder}/${humpTableName}/form`
    const validateFileName = `@/${config.vendorFolder}/${humpTableName}/validate`
    if (fs.existsSync(fileName)) {
      // file is exist
      console.log(`======file is existed and ignore to created template ${type}:${tableName}=======`)
    } else {
      if (!fs.existsSync(folder)) {
        fs.mkdirSync(folder, { recursive: true }, (err) => {
          if (err) throw err
        })
      }
      let templates = ''
      const imports = []
      const components = []
      let temp = {}
      const otherFuncs = []
      for (const i in columns) {
        if (columns[i].columnComment.indexOf('ignored') > -1) {
          continue // 忽略创建当前组件
        } else if (config.db.templateExceptedFields.split(',').findIndex((except) => except === columns[i].columnName) > -1) {
          // 去掉表_id 和其他字段
          continue // 忽略创建当前组件
        }
        let activeValue = ''
        let inactiveValue = ''
        let activeText = ''
        let inactiveText = ''
        let table = ''
        let url = ''
        const desc = reflectDesc(columns[i])
        const options = reflectOptions(columns[i])
        let keys = []
        let params = { step: 0, min: 0, max: 0 }
        let range = ''
        if (type == 'detail') {
          templates += `
            <el-form-item label="${desc}">
              {{ form.${columns[i].columnName} }}
            </el-form-item>
          `
        } else {
          switch (reflectComponent(columns[i])) {
            case 'inputNumber':
              params = reflectInputNumberParams(columns[i])
              templates += inputNumber(columns[i].columnName, desc, params.min, params.max, params.step)
              break
            case 'checkbox':
              templates += checkbox(options, columns[i].columnName, desc)
              break
            case 'radio':
              templates += radio(options, columns[i].columnName, desc)
              break
            case 'datePicker':
              templates += datePicker(columns[i].columnName, desc)
              break
            case 'datimePicker':
              templates += datimePicker(columns[i].columnName, desc)
              break
            case 'input':
              templates += input(columns[i].columnName, desc)
              break
            case 'textarea':
              templates += textarea(columns[i].columnName, desc)
              break
            case 'selectSingle':
              // create restful api
              if (columns[i].reflectColumnName.indexOf('_id') > -1) {
                // 关联表
                table = columns[i].reflectColumnName.replace(/_id/, '')
                url = `${config.select.requestPrefix}/${table}/select`
                templates += select(url, columns[i].columnName, true, desc)
                if (components.findIndex(item => item === 'Select') === -1) {
                  imports.push('import Select from \'@/components/Select.vue\'')
                }
                components.push('Select')
              } else {
                // 普通下拉
                templates += elSelect(columns[i].columnName, options, desc, true)
              }
              break
            case 'selectMulti':
              // create restful api
              table = columns[i].reflectColumnName.replace(/_ids/, '')
              url = `${config.select.requestPrefix}/${table}/select`
              templates += select(url, columns[i].columnName, false, desc)
              if (components.findIndex(item => item === 'Select') === -1) {
                imports.push('import Select from \'@/components/Select.vue\'')
                components.push('Select')
              }
              break
            case 'timePicker':
              templates += timePicker(columns[i].columnName, desc)
              break
            case 'formSwitch':
              keys = Object.keys(options)
              if (keys.length === 2) {
                activeText = keys[0]
                activeValue = options[keys[0]]
                inactiveText = keys[1]
                inactiveValue = options[keys[1]]
              }
              templates += formSwitch(activeValue, inactiveValue, activeText, inactiveText, columns[i].columnName, desc)
              break
            case 'uploadImage':
              // single image
              imports.push('import UploadImg from \'@/components/uploadImg/UploadImg.vue\'')
              temp = uploadImage(columns[i].columnName, desc, 0, 0, false, type !== 'detail')
              templates += temp.template
              if (temp.func) {
                otherFuncs.push(temp.func)
              }
              break
            case 'uploadImages':
              // multiple images
              imports.push('import UploadImg from \'@/components/uploadImg/UploadImg.vue\'')
              if (columns[i].columnComment.indexOf('range=') > -1) {
                range = columns[i].columnComment.split('range=')[1]
              }
              if (columns[i].columnComment.indexOf('max=') > -1) {
                const max = columns[i].columnComment.split('max=')[1]
                temp = uploadImage(columns[i].columnName, desc, max, range, true, type !== 'detail')
              } else if (range) {
                const max = range.split(',')[1]
                temp = uploadImage(columns[i].columnName, desc, max, range, true, type !== 'detail')
              }
              templates += temp.template
              if (temp.func) {
                otherFuncs.push(temp.func)
              }
              break
            case 'richText':
              templates += richText(columns[i].columnName, desc)
              break
            case 'tags':
              imports.push('import Tag from \'@/components/tag/Tag.vue\'')
              if (columns[i].columnComment.indexOf('range=') > -1) {
                range = columns[i].columnComment.split('range=')[1]
              }
              if (columns[i].columnComment.indexOf('max=') > -1) {
                const max = columns[i].columnComment.split('max=')[1]
                temp = tag(columns[i].columnName, desc, type !== 'detail', max)
              } else if (range) {
                const max = range.split(',')[1]
                temp = tag(columns[i].columnName, desc, type !== 'detail', max)
              }
              templates += temp.template
              if (temp.func) {
                otherFuncs.push(temp.func)
              }
              break
          }
        }

      }
      let buttons = ''
      switch (type) {
        case 'add':
          buttons = '<el-button type="primary" @click="resetForm(ruleFormRef)">重置</el-button>\n\t\t\t<el-button type="success" @click="submitForm(ruleFormRef)">提交</el-button>'
          break
        case 'update':
          buttons = '<el-button type="primary" @click="resetForm(ruleFormRef)">重置</el-button>\n\t\t\t<el-button type="success" @click="submitForm(ruleFormRef)">提交</el-button>'
          break
        case 'detail':
          // buttons = '<el-button type="primary" @click="back">返回</el-button>'
          break
      }
      const content = getTemplate(templates, buttons, formFileName, validateFileName, imports, type, tableName, config.vendorFolder, otherFuncs.join('\n'))
      if (fs.existsSync(fileName)) {
        // file is exist
        console.log(`======file is existed and ignored to created  ${type} template:${tableName}=======`)
      } else {
        fs.writeFile(fileName, content, { flag: 'a' }, (err) => {
          if (err) {
            console.log('========error======')
            throw err
          } else {
            console.log(`======succeessfully created template ${type} :${tableName}=======`)
          }
        })
      }
    }
  })
}
export const crateViewListTemplate = (columns, tableName) => {
  fs.readFile('src/scripts/config.json', 'utf8', (err, data) => {
    if (err) throw err
    config = JSON.parse(data)
    const humpTableName = formatToHump(tableName)
    const humpUpTableName = formatToUpHump(tableName)
    const folder = `${config.view.folder}/${humpTableName}`
    const fileName = `${folder}/list.vue`
    let keywords = ''
    const components = []
    const imports = []
    let table = ''
    let url = ''
    let templates = ''
    let datePickerCount = 1
    let datesScipt = ''
    let existKeywords = false
    columns.map((item, i) => {
      const options = reflectOptions(item)
      let desc = reflectDesc(item)
      if (item.isResearch) {
        // 加入搜索
        if (item.isKeyword) {
          // 加入keyword关键字搜索
          keywords += desc + ' '
          existKeywords = true
        } else if (item.realatedEndTime) {
          // 关联时间搜索
          if (item.realatedEndTime == 'self') {
            templates += dateRange(`dates_${datePickerCount}`, `sel_date_${datePickerCount}`, '', 'search-item')
            datesScipt += `const dates_${datePickerCount} = ref<Array<any>>([])\n` +
              ` onMounted(() => {
                  if (${humpTableName}Filters.c_time_range) {
                    const d = JSON.parse(${humpTableName}Filters.c_time_range as string)
                    const startDate = new Date(d[0] * 1000)
                    const endDate = new Date(d[0] * 1000)
                    dates_1.value[0] = startDate.getFullYear() + '-' + (startDate.getMonth() >= 9 ? startDate.getMonth() + 1 : '0' + (startDate.getMonth() + 1)) + '-' + startDate.getDate()
                    dates_1.value[1] = endDate.getFullYear() + '-' + (endDate.getMonth() >= 9 ? endDate.getMonth() + 1 : '0' + (endDate.getMonth() + 1)) + '-' + endDate.getDate()
                  }
                })\n`+
              `const sel_date_${datePickerCount} = (value: Array<number>) => {
              if (value && value.length >0) {
                    ${humpTableName}Filters.c_time_range = JSON.stringify([value[0] / 1000, value[1] / 1000])
                } else {
                    ${humpTableName}Filters.c_time_range = ''
                }
             }`
            datePickerCount += 1
          } else {
            // 关联自己
            templates += dateRange(`dates_${datePickerCount}`, `sel_date_${datePickerCount}`, '', 'search-item')
            datesScipt += `const dates_${datePickerCount} = ref<Array<any>>([])\n` +
              ` onMounted(() => {
                  if (${humpTableName}Filters.c_time_range) {
                    const d = JSON.parse(${humpTableName}Filters.c_time_range as string)
                    const startDate = new Date(d[0] * 1000)
                    const endDate = new Date(d[0] * 1000)
                    dates_1.value[0] = startDate.getFullYear() + '-' + (startDate.getMonth() >= 9 ? startDate.getMonth() + 1 : '0' + (startDate.getMonth() + 1)) + '-' + startDate.getDate()
                    dates_1.value[1] = endDate.getFullYear() + '-' + (endDate.getMonth() >= 9 ? endDate.getMonth() + 1 : '0' + (endDate.getMonth() + 1)) + '-' + endDate.getDate()
                  }
                })\n`+
              `const sel_date_${datePickerCount} = (value: Array<number>) => {
                 if (value && value.length >0) {
                     ${humpTableName}Filters.c_time_range = JSON.stringify([value[0] / 1000, value[1] / 1000])
                  } else {
                     ${humpTableName}Filters.c_time_range = ''
                  }
            }`
            datePickerCount += 1
          }

        } else {
          // 普通搜索
          switch (reflectComponent(columns[i])) {
            case 'selectSingle':
              // create restful api
              if (columns[i].columnName.indexOf('_id') > -1) {
                // 关联表
                table = columns[i].columnName.replace(/_id/, '')
                url = `${config.select.requestPrefix}/${table}/select`
                templates += select(url, columns[i].columnName, true, desc, `${humpTableName}Filters`, 'search-item')
                if (components.findIndex(item => item === 'Select') === -1) {
                  imports.push('import Select from \'@/components/Select.vue\'')
                }
                components.push('Select')
              } else {
                // 普通下拉
                templates += searchElSelect(columns[i].columnName, options, desc, true, `${humpTableName}Filters`, 'search-item')
              }
              break
            case 'selectMulti':
              // create restful api
              table = columns[i].columnName.replace(/_ids/, '')
              url = `${config.select.requestPrefix}/${table}/select`
              templates += select(url, columns[i].columnName, false, '', `${humpTableName}Filters`, 'search-item')
              if (components.findIndex(item => item === 'Select') === -1) {
                imports.push('import Select from \'@/components/Select.vue\'')
                components.push('Select')
              }
              break
          }
        }
      }
    })
    if (keywords != '' && existKeywords) {
      templates = ` <el-form-item class="keywords search-item"><el-input placeholder="输入${keywords}搜索" class="keywords search-item" v-model="${humpTableName}Filters.keywords" /> </el-form-item>` + templates + `<el-form-item class='search-item'>  <el-button type="warning" @click='add'>新增</el-button> </el-form-item>`
    }

    const content = `
<template>
  <Table :columns="${humpTableName}Columns" :list="${humpTableName}List" :tableId="'${humpTableName}_id'">
<template #search>
<el-form style="display:flex;flex-wrap:wrap">
${templates}
</el-form>
</template>
<template #pagination>
  <el-pagination layout="prev, pager, next, jumper" :total="${humpTableName}Total" @current-change="handleCurrentChange" />
</template>
  </Table>
</template>
<script lang="ts" setup>
import { ref,onMounted } from 'vue'
import _router from '@/router';
import Table from '@/components/table/Table.vue'
${imports.join('\n')}
import { Get${humpUpTableName} } from '@/${config.vendorFolder.replace(/src\//, '')}/${humpTableName}/${humpTableName}'

const {
    list${humpUpTableName},
    ${humpTableName}Total,
    ${humpTableName}List,
    ${humpTableName}Page,
    ${humpTableName}Columns,
    ${humpTableName}Filters,
    } = Get${humpUpTableName}()
list${humpUpTableName}()
const handleCurrentChange = (value: number) => {
  ${humpTableName}Page.value = value
  list${humpUpTableName}()
}

const add = ()=>{
  _router.push({
    name:'${humpTableName}Add',
  })
}


${datesScipt}
</script>
<style scoped lang='scss'>
.keywords {
  width: 230px;
}

.search-item {
  margin-right: 10px;
}
</style>
`
    if (fs.existsSync(fileName)) {
      // file is exist
      console.log(`======file is existed and ignored to created  list template:${tableName}=======`)
    } else {
      fs.writeFile(fileName, content, { flag: 'a' }, (err) => {
        if (err) {
          console.log('========error======')
          throw err
        } else {
          console.log(`======succeessfully created template list :${tableName}=======`)
        }
      })
    }
  })
}
const getTemplate = (templates, buttons, formFileName, validateFileName, imports, type, tableName = '', vendorFolder = '', otherFuncs = '') => {
  const model = formatToUpHump(tableName)
  const humpTableName = formatToHump(tableName)
  let importApi = `import { Get${model} } from '@/${vendorFolder.replace(/src\//, '')}/${humpTableName}/${humpTableName}'`

  let exportApi = `const { ${formatToHump(tableName)}} = Get${model}()`
  if (type === 'add' || type === 'update') {
    let api = ''
    if (type === 'add') {
      api = `add${model}`
    } else if (type === 'update') {
      api = `update${model}`
      importApi += `\n
        import { useRoute } from 'vue-router'
      `
      otherFuncs += `\n
        const route  = useRoute()
        form.value.${tableName}_id =  parseInt(route.query.id as string)
        get${model}()
      `
    } else {
      api = `get${model},get${model}`
      otherFuncs += `\n
        get${model}()
      `
    }
    exportApi = `const { ${api},${formatToHump(tableName)}} = Get${model}()`
    const msg = type == 'add' ? '\"添加成功\"' : '\"修改成功\"'
    return `
<template>
  <el-form  :rules="rules" ref="ruleFormRef" :model="form" class="demo-ruleForm">
    ${templates}
    <el-form-item>
      <div style="width:100%;">
      ${buttons}
      </div>
    </el-form-item>
  </el-form>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
${importApi}
import { getListener } from '@/composables/listener'
import { validate } from '${validateFileName.replace(/src\//, '')}'
import type { FormInstance, FormRules } from 'element-plus'
${imports.join('\n')}
import { message, MessageType } from '@/components/message/message'
const ruleFormRef = ref<FormInstance>()
const rules = reactive<FormRules>(validate)
import router from '@/router'
const {
  windowBeforeunload,
  removeWindowBfunload
} = getListener()
${exportApi}
const form = ${formatToHump(tableName)}
windowBeforeunload()
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate((valid:any, fields:any) => {
    if (valid) {
      // success
      ${api}(()=>{
          removeWindowBfunload()
          message(${msg} , MessageType.success)
          resetForm(formEl)
          router.back()
      })
    } else {
      console.log('error submit!', fields)
    }
  })
}
const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
}
${otherFuncs}
</script>
<style lang="scss" scoped>
</style>`
  } else {
    return `
<template>
  <el-form label-width="120px" :model="form" class="demo-ruleForm" label-position="left">
    ${templates}
    <div style="text-align:center">
      ${buttons}
    </div>
  </el-form>
</template>
<script lang="ts" setup>
import { useRoute } from 'vue-router'
import router from '@/router'
${imports.join('\n')}
${importApi}
${exportApi}
${otherFuncs}
const form = ${formatToHump(tableName)}
const route = useRoute()
form.value.${tableName}_id = parseInt(route.query.${tableName}_id as string)
Get${model}()
const back = () => {
  router.back()
}
</script>
<style lang="scss" scoped>
</style>`
  }
}
